package net.cassite.daf4j.stream;

import net.cassite.daf4j.*;

/**
 * Stream式查询基类
 *
 * @param <E> 实体类型
 * @param <T> QueryStream类型
 */
public abstract class QueryStreamBase<E, T extends QueryStreamBase<E, T>> {
        final E entity;
        final DataAccess dataAccess;
        AndOr andOr;
        QueryParameter parameter;

        protected QueryStreamBase(E entity, DataAccess dataAccess) {
                this.entity = entity;
                this.dataAccess = dataAccess;
        }

        /**
         * 根据给出条件筛选
         *
         * @param andOr 筛选依据
         * @return 筛选后的Stream
         */
        @SuppressWarnings("unchecked")
        public T filter(AndOr andOr) {
                if (this.andOr == null) {
                        this.andOr = andOr;
                } else {
                        if (andOr instanceof And) {
                                this.andOr.and((And) andOr);
                        } else if (andOr instanceof Or) {
                                this.andOr.and((Or) andOr);
                        } else if (andOr instanceof Condition) {
                                this.andOr.and((Condition) andOr);
                        } else if (andOr instanceof ExpressionBoolean) {
                                this.andOr.and((ExpressionBoolean) andOr);
                        }
                }
                return (T) this;
        }

        /**
         * 对结果进行排序.<br>
         * 实体需要实现SortedEntity来提供排序依据.若没有实现该接口则会抛出异常
         *
         * @return 排序后的Stream
         * @see SortedEntity
         */
        @SuppressWarnings("unchecked")
        public T sorted() {
                if (entity instanceof SortedEntity) {
                        sorted(((SortedEntity) entity).sorted());
                } else {
                        throw new UnsupportedOperationException("Entity is not a SortedEntity");
                }
                return (T) this;
        }

        /**
         * 根据给出的排序依据进行排序
         *
         * @param order 排序依据
         * @return 排序后的Stream
         */
        @SuppressWarnings("unchecked")
        public T sorted(OrderBase... order) {
                if (parameter == null) {
                        parameter = new QueryParameter();
                }
                parameter.orderBy(order);
                return (T) this;
        }

        /**
         * 限制结果List的长度
         *
         * @param count 结果长度
         * @return 限制长度的Stream
         */
        @SuppressWarnings("unchecked")
        public T limit(int count) {
                if (parameter == null) {
                        parameter = new QueryParameter();
                }
                parameter.top(count);
                return (T) this;
        }

        /**
         * 限制结果List的长度
         *
         * @param start 结果从该游标开始计算
         * @param end   结果以该游标结束
         * @return 限制长度的Stream
         */
        @SuppressWarnings("unchecked")
        public T limit(int start, int end) {
                if (parameter == null) {
                        parameter = new QueryParameter();
                }
                parameter.limit(start, end);
                return (T) this;
        }

        /**
         * 取不重复的记录
         *
         * @return stream本身
         */
        @SuppressWarnings("unchecked")
        public T distinct() {
                if (parameter == null) {
                        parameter = new QueryParameter();
                }
                parameter.distinct();
                return (T) this;
        }

        /**
         * 转换为PreResult格式,方便进行子查询
         *
         * @return PreResult
         */
        public PreResult<E> toPreRes() {
                PreResult<E> preResult = new PreResult<E>(dataAccess, entity, andOr);
                preResult.parameter = this.parameter;
                return preResult;
        }

}
